//
//  Httphelper.m
//  PhoneApp
//
//  Created by SL on 15/3/6.
//  Copyright (c) 2015年 Sheng long. All rights reserved.
//

#import "AppHttphelper.h"
#import "NetStatusHelper.h"
#import <AFNetworking/AFNetworking.h>
#import <AFNetworking/AFNetworkActivityIndicatorManager.h>
#import "AppMacro.h"

typedef NS_ENUM(NSInteger,HTTP_TYPE) {
    HTTP_GET,
    HTTP_POST,
    HTTP_UPLOAD,
};

@interface AppHttphelper ()

@property (atomic,assign) NSInteger netWorking;

@end

@implementation AppHttphelper

+ (AppHttphelper *)sharedInstance {
    static AppHttphelper *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[AppHttphelper alloc] init];
    });
    return sharedInstance;
}

+ (RACSignal *)GET:(NSString *)url
            params:(id)params{
    return [self Http:url
               params:params
                 type:HTTP_GET
            filePaths:nil
             fileData:nil
             fileName:nil];
}

+ (RACSignal *)POST:(NSString *)url
             params:(id)params{
    return [self Http:url
               params:params
                 type:HTTP_POST
            filePaths:nil
             fileData:nil
             fileName:nil];
}

+ (RACSignal *)UPLOAD:(NSString *)url
               params:(id)params
            filePaths:(NSArray *)filePaths
             fileData:(NSData *)fileData
             fileName:(NSString *)fileName {
    return [self Http:url
               params:params
                 type:HTTP_UPLOAD
            filePaths:filePaths
             fileData:fileData
             fileName:fileName];
}

+ (RACSignal *)httpHead:(NSString *)url{
#ifdef DEBUG
    NSLog(@"head地址:%@",url);
#endif
    return [[[RACSignal createSignal:^RACDisposable *(id < RACSubscriber > subscriber) {
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        //设置返回的数据解析格式
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
        //测试在20kb速度的时候4s超时还是可以正常的，因此设置最小值为4s
        [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
        manager.requestSerializer.timeoutInterval = 4.f;
        [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
        
        __block id < RACSubscriber > _subscriber = subscriber;
        __block NSURLSessionDataTask *task = nil;
        
        task = [manager HEAD:url
                  parameters:nil
                     success:^(NSURLSessionDataTask * _Nonnull task) {
                         [_subscriber sendNext:@1];
                         [_subscriber sendCompleted];
                     } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                         //-999是自动取消请求，-1001是超时
                         NSError *err = [NSError errorWithDomain:AppCustomErrorDomain code:error.code userInfo:nil];
                         [_subscriber sendError:err];
                     }];
        [task resume];
        return [RACDisposable disposableWithBlock:^{
            CLog(@"取消请求");
            [task cancel];
        }];
    }] doNext:^(id x) {
        CLog(@"\n\nhead请求成功\n%@\n%@\n\n",url,x);
    }] doError:^(NSError *error) {
        CLog(@"\n\nhead请求失败\n%@\n%@\n\n",url,error);
    }];
}

+ (RACSignal *)Http:(NSString *)url
             params:(id)params
               type:(HTTP_TYPE)type
          filePaths:(NSArray *)filePaths
           fileData:(NSData *)fileData
           fileName:(NSString *)fileName {
    if ([NetStatusHelper sharedInstance].netStatus == NoneNet) {
        return [RACSignal error:AppErrorSetting(AppErrorMsg_NoNet)];
    }
    
    if ([params isKindOfClass:[NSDictionary class]]) {
        NSMutableDictionary *info = [NSMutableDictionary dictionaryWithDictionary:params];
        int iRandom = arc4random();
        [info setValue:@(iRandom) forKey:@"_t"];
        params = info;
    }
    
    if (type != HTTP_UPLOAD) {
        if (params) {
            NSMutableString *pramstr = [NSMutableString stringWithString:url];
            [params enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
                [pramstr appendFormat:@"%@%@=%@",([pramstr isEqualToString:url]?@"?":@"&"),key,obj];
            }];
#ifdef DEBUG
            NSLog(@"HTTP::::%@", pramstr);
#endif
        }
    }
    
    return [[[RACSignal createSignal:^RACDisposable *(id < RACSubscriber > subscriber) {
        NSMutableURLRequest *request = nil;
        if (type==HTTP_UPLOAD) {
            request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST"
                                                                                 URLString:url
                                                                                parameters:params
                                                                 constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                                                                     NSMutableArray *fileArray = [NSMutableArray new];
                                                                     if (filePaths.count) {
                                                                         [filePaths enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                                                                             NSData *data = [NSData dataWithContentsOfFile:obj];
                                                                             [fileArray addObject:@{
                                                                                                    @"data":data,
                                                                                                    @"name":[obj lastPathComponent],
                                                                                                    }];
                                                                         }];
                                                                     }
                                                                     if (fileData && fileName) {
                                                                         [fileArray addObject:@{
                                                                                                @"data":fileData,
                                                                                                @"name":fileName,
                                                                                                }];
                                                                     }
                                                                     [fileArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                                                                         [formData appendPartWithFileData:obj[@"data"]
                                                                                                     name:[obj[@"name"] stringByDeletingPathExtension]
                                                                                                 fileName:obj[@"name"]
                                                                                                 mimeType:@"application/octet-stream"];
                                                                     }];
                                                                 }
                                                                                     error:nil];
        }else {
            request = [[AFHTTPRequestSerializer serializer] requestWithMethod:(type==HTTP_GET?@"GET":@"POST")
                                                                    URLString:url
                                                                   parameters:params
                                                                        error:nil];
        }
        
        __block id < RACSubscriber > _subscriber = subscriber;
        __block NSURLSessionDataTask *task = nil;
        
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
        
        task = [manager dataTaskWithRequest:request
                          completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                              if ([AFNetworkActivityIndicatorManager sharedManager].enabled) {
                                  [self sharedInstance].netWorking--;
                                  if ([self sharedInstance].netWorking <= 0) {
                                      [self sharedInstance].netWorking = 0;
                                      [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
                                  }
                              }
                              //-999是自动取消请求，-1001是超时
                              if (error) {
                                  //-999是请求超时
                                  if (error.code != -999) {
                                      if (error.code == 404) {
                                          [_subscriber sendError:AppErrorSetting(@"404")];
                                      }else if (error.code == -1001){
                                          [_subscriber sendError:AppErrorSetting(@"请求超时")];
                                      }else {
                                          NSError *err = [NSError errorWithDomain:AppCustomErrorDomain
                                                                             code:error.code
                                                                         userInfo:@{AppErrorMsg:[NSString stringWithFormat:@"%@-%d",AppErrorMsg_Failed,error.code]}];
                                          [_subscriber sendError:err];
                                      }
                                  }
                              } else {
                                  BOOL success = YES;
                                  if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
                                      NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
                                      if (r.statusCode > 299) {
                                          NSError *err = [NSError errorWithDomain:AppCustomErrorDomain
                                                                             code:r.statusCode
                                                                         userInfo:@{AppErrorMsg:[NSString stringWithFormat:@"%@-%d",AppErrorMsg_Failed,r.statusCode]}];
                                          [_subscriber sendError:err];
                                          success = NO;
                                      }
                                  }
                                  if (success) {
                                      [_subscriber sendNext:responseObject];
                                      [_subscriber sendCompleted];
                                  }
                              }
                          }];
        if ([AFNetworkActivityIndicatorManager sharedManager].enabled) {
            [self sharedInstance].netWorking++;
            [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
        }
        [task resume];
        return [RACDisposable disposableWithBlock:^{
            CLog(@"取消请求");
            [task cancel];
        }];
    }] doNext:^(id x) {
        CLog(@"\n\n请求成功\n%@\n%@\n%@\n\n",url,params,x);
    }] doError:^(NSError *error) {
        CLog(@"\n\n请求失败\n%@\n%@\n%@\n\n",url,params,error);
    }];
}

+ (RACSignal *)downloadFileURL:(NSString *)aUrl
                      fileName:(NSString *)fileName
                          save:(BOOL)save {
    
    return [[[RACSignal createSignal:^RACDisposable *(id < RACSubscriber > subscriber) {
        __block id < RACSubscriber > _subscriber = subscriber;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
        
        NSURL *URL = [NSURL URLWithString:aUrl];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];
        
        NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request
                                                                         progress:nil
                                                                      destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
                                                                          //创建附件存储目录
                                                                          NSMutableArray *array = [NSMutableArray arrayWithArray:[fileName componentsSeparatedByString:@"/"]];
                                                                          [array removeLastObject];
                                                                          if (![fileManager fileExistsAtPath:[array componentsJoinedByString:@"/"]]) {
                                                                              [fileManager createDirectoryAtPath:[array componentsJoinedByString:@"/"]
                                                                                     withIntermediateDirectories:YES
                                                                                                      attributes:nil
                                                                                                           error:nil];
                                                                          }
                                                                          return [NSURL fileURLWithPath:fileName];
                                                                      }
                                                                completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
#ifdef DEBUG
                                                                    NSLog(@"File downloaded to: %@", filePath);
#endif
                                                                    if ([AFNetworkActivityIndicatorManager sharedManager].enabled) {
                                                                        [self sharedInstance].netWorking--;
                                                                        if ([self sharedInstance].netWorking <= 0) {
                                                                            [self sharedInstance].netWorking = 0;
                                                                            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
                                                                        }
                                                                    }
                                                                    //-999是自动取消请求，-1001是超时
                                                                    if (error) {
                                                                        //-999是请求超时
                                                                        if (error.code != -999) {
                                                                            if (error.code == 404) {
                                                                                [_subscriber sendError:AppErrorSetting(@"404")];
                                                                            }else if (error.code == -1001){
                                                                                [_subscriber sendError:AppErrorSetting(@"请求超时")];
                                                                            }else {
                                                                                NSError *err = [NSError errorWithDomain:AppCustomErrorDomain
                                                                                                                   code:error.code
                                                                                                               userInfo:@{AppErrorMsg:[NSString stringWithFormat:@"%@-%d",AppErrorMsg_Failed,error.code]}];
                                                                                [_subscriber sendError:err];
                                                                            }
                                                                        }
                                                                    } else {
                                                                        BOOL success = YES;
                                                                        if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
                                                                            NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
                                                                            if (r.statusCode > 299) {
                                                                                NSError *err = [NSError errorWithDomain:AppCustomErrorDomain
                                                                                                                   code:r.statusCode
                                                                                                               userInfo:@{AppErrorMsg:[NSString stringWithFormat:@"%@-%d",AppErrorMsg_Failed,r.statusCode]}];
                                                                                [_subscriber sendError:err];
                                                                                success = NO;
                                                                            }
                                                                        }
                                                                        if (success) {
                                                                            NSData *data = [NSData dataWithContentsOfFile:fileName];
                                                                            if (!save) {
                                                                                [fileManager removeItemAtPath:filePath
                                                                                                        error:nil];
                                                                            }
                                                                            [_subscriber sendNext:data];
                                                                            [_subscriber sendCompleted];
                                                                        }
                                                                    }
                                                                }];
        if ([AFNetworkActivityIndicatorManager sharedManager].enabled) {
            [self sharedInstance].netWorking++;
            [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
        }
        [downloadTask resume];
        return [RACDisposable disposableWithBlock:^{
            CLog(@"取消请求");
            if (downloadTask) {
                [downloadTask cancel];
            }
        }];
    }] doNext:^(id x) {
        CLog(@"\n\n下载成功\n%@\n%@\n\n",aUrl,fileName);
    }] doError:^(NSError *error) {
        CLog(@"\n\n下载失败\n%@\n%@\n\n",aUrl,fileName);
    }];
}
//
//+ (RACSignal *)SYNC:(NSString *)url params:(id)params{
//
//    if ([NetStatusHelper sharedInstance].netStatus == NoneNet) {
//        return [RACSignal error:AppErrorSetting(AppErrorMsg_NoNet)];
//    }
//
//    AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
//    NSMutableURLRequest *request = [requestSerializer requestWithMethod:@"GET"
//                                                              URLString:url
//                                                             parameters:params
//                                                                  error:nil];
//
//    /* 最终继承自 NSOperation，看到这个，大家可能就知道了怎么实现同步的了，也就是利用 NSOperation 来做的同步请求 */
//    AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
//    AFHTTPResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer];
//
//    [requestOperation setResponseSerializer:responseSerializer];
//
//    [requestOperation start];
//
//    [requestOperation waitUntilFinished];
//
//    /* 请求结果 */
//    NSString *result = [requestOperation responseString];
//
//    if (result != nil) {
//        return [RACSignal return:result];
//    }
//    return [RACSignal error:nil];
//}

@end
